package com.motu.monstercity.server.game.logichandler;

import com.motu.monstercity.module.common.network.RequestParam;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.CsGameRestaurant.*;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.skill.Skill;
import com.motu.monstercity.server.game.commondata.restaurant.*;
import com.motu.monstercity.server.game.log.LogType;
import com.motu.monstercity.server.game.logic.*;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.toolset.ErrorWord;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonArray;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class RestaurantHandler {

    // CMD_GAME_RESTAURANT_MAIN_INFO = 73301; // 中餐厅的用户数据 [1]第一次请求
    public static Object CMD_GAME_RESTAURANT_MAIN_INFO(RequestParam clientParam) throws Exception {
        CSGameRestaurantMainInfoRequest request = CSGameRestaurantMainInfoRequest.parseFrom(clientParam.getData());
        CSGameRestaurantMainInfoResponse.Builder response = CSGameRestaurantMainInfoResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserPower userPower = GameUser.getUserPower(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserRestaurantInfo userRestaurantInfo = RestaurantManager.getUserRestaurantInfo(userId);
        RestaurantManager.unlockDefaultData(pbUserData, userInfo, userPower, userRestaurantInfo);

        ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantInfo, true);

        for (UserRestaurantRoom userRestaurantRoom : RestaurantManager.getUserRestaurantRoomList(userId)) {
            ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantRoom, true);
        }
        for (UserRestaurantFood userRestaurantFood : RestaurantManager.getUserRestaurantFoodList(userId)) {
            ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantFood, true);
        }

        return response;
    }

    // CMD_GAME_RESTAURANT_ROOM_UNLOCK = 73302; // 餐厅解锁
    public static Object CMD_GAME_RESTAURANT_ROOM_UNLOCK(RequestParam clientParam) throws Exception {
        CSGameRestaurantRoomUnlockRequest request = CSGameRestaurantRoomUnlockRequest.parseFrom(clientParam.getData());
        CSGameRestaurantRoomUnlockResponse.Builder response = CSGameRestaurantRoomUnlockResponse.newBuilder();
        long userId = clientParam.getUserId();

        int restaurantId = request.getRestaurantId();
        RestaurantMain restaurantMain = RestaurantManager.getRestaurantMain(restaurantId);
        if (restaurantMain == null) {
            return ErrorWord.NOT_DATA;// 未配置
        }


        UserRestaurantInfo userRestaurantInfo = RestaurantManager.getUserRestaurantInfo(userId);
        if (Tool.isInList(userRestaurantInfo.getUnlockRoomArray(), restaurantId)) {
            return ErrorWord.REPEATED_OPERATION;// 已经解锁过了
        }

        if (userRestaurantInfo.getTotalGuest() < restaurantMain.getUnlockValue()) {
            return ErrorWord.ITEM_LACK;// 总的接待人数不足
        }


        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserPower userPower = GameUser.getUserPower(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();

        RestaurantManager.unlockRestaurantRoom(pbUserData, userInfo, userPower, userRestaurantInfo, restaurantId);// 解锁餐厅，
        userRestaurantInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantInfo);

        return response;
    }

    // CMD_GAME_RESTAURANT_ROOM_LEVEL_UP = 73303; // 餐厅升级（解锁美食攻略）
    public static Object CMD_GAME_RESTAURANT_ROOM_LEVEL_UP(RequestParam clientParam) throws Exception {
        CSGameRestaurantRoomLevelUpRequest request = CSGameRestaurantRoomLevelUpRequest.parseFrom(clientParam.getData());
        CSGameRestaurantRoomLevelUpResponse.Builder response = CSGameRestaurantRoomLevelUpResponse.newBuilder();
        long userId = clientParam.getUserId();

        int restaurantId = request.getRestaurantId();
        RestaurantMain restaurantMain = RestaurantManager.getRestaurantMain(restaurantId);
        if (restaurantMain == null) {
            return ErrorWord.NOT_DATA;// 未配置
        }

        UserRestaurantInfo userRestaurantInfo = RestaurantManager.getUserRestaurantInfo(userId);
        if (!Tool.isInList(userRestaurantInfo.getUnlockRoomArray(), restaurantId)) {
            return ErrorWord.WRONG_STATUS;// 未解锁
        }

        UserRestaurantRoom userRestaurantRoom = RestaurantManager.getUserRestaurantRoom(userId, restaurantId);
        if (userRestaurantRoom == null) {
            return ErrorWord.WRONG_STATUS;// 未解锁
        }

        int nextLevel = userRestaurantRoom.getLevel() + 1;//  升级后的等级
        RestaurantUpgrade restaurantUpgrade = RestaurantManager.getRestaurantUpgrade(restaurantId, nextLevel);
        if (restaurantUpgrade == null) {
            return ErrorWord.ALREADY_MAX;// 已经最大等级
        }

        int itemId = ItemId.RESTAURANT_ROOM_UPGRADE_ITEM;// 中餐厅餐厅图纸，升级餐厅略用
        UserInfo userInfo = GameUser.getUserInfo(userId);
        long userItemNum = BagManager.getUserItemNum(userInfo, itemId);
        if (userItemNum < restaurantUpgrade.getUpgradeConsume()) {
            return ErrorWord.ITEM_LACK;// 道具不足
        }

        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserPower userPower = GameUser.getUserPower(userId);
        RewardManager.subReward(userInfo, itemId, restaurantUpgrade.getUpgradeConsume(), pbUserData, LogType.RESTAURANT_ROOM_UPGRADE, restaurantId + "_" + nextLevel);
        userRestaurantRoom.putLevel(pbUserData, userInfo, userPower, userRestaurantInfo, nextLevel, true);
        userRestaurantRoom.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantRoom);

        return response;
    }

    // CMD_GAME_RESTAURANT_FOOD_LEVEL_UP = 73304; // 美食攻略升级
    public static Object CMD_GAME_RESTAURANT_FOOD_LEVEL_UP(RequestParam clientParam) throws Exception {
        CSGameRestaurantFoodLevelUpRequest request = CSGameRestaurantFoodLevelUpRequest.parseFrom(clientParam.getData());
        CSGameRestaurantFoodLevelUpResponse.Builder response = CSGameRestaurantFoodLevelUpResponse.newBuilder();
        long userId = clientParam.getUserId();

        int foodId = request.getFoodId();
        RestaurantFood restaurantFood = RestaurantManager.getRestaurantFood(foodId);
        if (restaurantFood == null) {
            return ErrorWord.NOT_DATA;// 未配置
        }

        UserRestaurantInfo userRestaurantInfo = RestaurantManager.getUserRestaurantInfo(userId);
        if (!Tool.isInList(userRestaurantInfo.getUnlockFoodArray(), foodId)) {
            return ErrorWord.WRONG_STATUS;// 未解锁
        }

        UserRestaurantFood userRestaurantFood = RestaurantManager.getUserRestaurantFood(userId, foodId);
        if (userRestaurantFood == null) {
            return ErrorWord.WRONG_STATUS;// 未解锁
        }

        int skillId = restaurantFood.getSkillId();// 技能id，配置在skill表
        Skill skill = SkillManager.getSkill(skillId);
        if (skill == null) {
            return ErrorWord.NOT_DATA;
        }

        int curLevel = userRestaurantFood.getLevel();
        int nextLevel = curLevel + 1;//  升级后的等级
        if (skill.getMaxLevel() > 0 && nextLevel > skill.getMaxLevel()) {
            return ErrorWord.ALREADY_MAX;//  已达到最大等级
        }

        int subItemNum = (int) skill.takeLevelUpItemNum(curLevel);// 需要消耗的熟练度数量
        if (userRestaurantFood.getSkillValue() < subItemNum) {
            return ErrorWord.ITEM_LACK;// 熟练度不足
        }

        //  执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();
        userRestaurantFood.subSkillValue(userInfo, subItemNum, LogType.RESTAURANT_FOOD_UPGRADE, foodId + "_" + curLevel);
        userRestaurantFood.putLevel(nextLevel);
        userRestaurantFood.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantFood);

        UserPower userPower = GameUser.getUserPower(userId);
        RestaurantManager.handleFoodLeveUp(pbUserData, userInfo, userPower, skill, nextLevel);// 美食攻略对应的技能升级，对相应性格的商业建筑有加成

        return response;
    }

    // CMD_GAME_RESTAURANT_FOOD_LEVEL_UP_ONEKEY = 73308; // 美食攻略升级，一键升级
    public static Object CMD_GAME_RESTAURANT_FOOD_LEVEL_UP_ONEKEY(RequestParam clientParam) throws Exception {
        CSGameRestaurantFoodLevelUpOnekeyRequest request = CSGameRestaurantFoodLevelUpOnekeyRequest.parseFrom(clientParam.getData());
        CSGameRestaurantFoodLevelUpOnekeyResponse.Builder response = CSGameRestaurantFoodLevelUpOnekeyResponse.newBuilder();
        long userId = clientParam.getUserId();

        //  执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();
        List<UserRestaurantFood> foodList = RestaurantManager.getUserRestaurantFoodList(userId);
        for (UserRestaurantFood userRestaurantFood : foodList) {
            userRestaurantFood.levelUpOneKey(pbUserData, userInfo);
        }

        // 全量更新
        UserPower userPower = GameUser.getUserPower(userId);
        String earnAddFood = RestaurantManager.getEarnAddFood(foodList);
        if (!earnAddFood.equals(userPower.getEarnAddFoodPer())) {
            userPower.putEarnAddFoodPer(earnAddFood);
            List<UserBuild> buildList = userPower.takeUserBuildList(0);// 所有的商业建筑
            BuildManager.batchUpdateBuildEarn(pbUserData, userInfo, userPower, buildList);
        }

        return response;
    }

    // CMD_GAME_RESTAURANT_GUEST_UNLOCK = 73305; // 客人解锁
    public static Object CMD_GAME_RESTAURANT_GUEST_UNLOCK(RequestParam clientParam) throws Exception {
        CSGameRestaurantGuestUnlockRequest request = CSGameRestaurantGuestUnlockRequest.parseFrom(clientParam.getData());
        CSGameRestaurantGuestUnlockResponse.Builder response = CSGameRestaurantGuestUnlockResponse.newBuilder();
        long userId = clientParam.getUserId();

        int guestId = request.getGuestId();
        RestaurantGuest restaurantGuest = RestaurantManager.getRestaurantGuest(guestId);
        if (restaurantGuest == null) {
            return ErrorWord.NOT_DATA;// 未配置
        }

        UserRestaurantInfo userRestaurantInfo = RestaurantManager.getUserRestaurantInfo(userId);
        JsonArray jsonArray = userRestaurantInfo.getUnlockGuestArray();
        if (Tool.isInList(jsonArray, guestId)) {
            return ErrorWord.REPEATED_OPERATION;// 已经解锁过了
        }

        if (userRestaurantInfo.getScore() < restaurantGuest.getUnlockValue()) {
            return ErrorWord.ITEM_LACK;// 人气值不达标
        }

        //  执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();
        jsonArray.add(guestId);
        userRestaurantInfo.putUnlockGuest(jsonArray.toString());
        userRestaurantInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantInfo);

        return response;
    }

    // CMD_GAME_RESTAURANT_RECEPTION = 73306; // 接待客人
    public static Object CMD_GAME_RESTAURANT_RECEPTION(RequestParam clientParam) throws Exception {
        CSGameRestaurantReceptionRequest request = CSGameRestaurantReceptionRequest.parseFrom(clientParam.getData());
        CSGameRestaurantReceptionResponse.Builder response = CSGameRestaurantReceptionResponse.newBuilder();
        long userId = clientParam.getUserId();

        int num = request.getNum();// 招待次数

        UserRestaurantInfo userRestaurantInfo = RestaurantManager.getUserRestaurantInfo(userId);
        if (userRestaurantInfo.getReceptionNum() < num) {
            return ErrorWord.ITEM_LACK;// 招待次数不足
        }

        if (userRestaurantInfo.getUnlockGuestArray().size() == 0 || userRestaurantInfo.getUnlockFoodArray().size() == 0) {
            return ErrorWord.NOT_DATA;//  模块未解锁
        }

        //  执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        List<UserRestaurantRoom> roomList = RestaurantManager.getUserRestaurantRoomList(userId);// 餐厅列表
        PBUserData.Builder pbUserData = response.getUserBuilder();

        int succNum = 0;// 成功接待的次数
        int totalScore = 0;// 总的人气值
        ConcurrentHashMap<Integer, Integer> skillAddMap = new ConcurrentHashMap<>(); // 熟练度增加的美食攻略列表
        ConcurrentHashMap<Integer, Integer> receptionAddMap = new ConcurrentHashMap<>(); // 招待次数增加的美食攻略列表
        for (int i=0;i<num;i++) {
            RestaurantFood restaurantFood = RestaurantManager.getRandomFood(userRestaurantInfo);
            RestaurantGuest restaurantGuest = RestaurantManager.getRandomGuest(userRestaurantInfo);

            response.addGuestIds(restaurantGuest.getId());// 下发客人id列表
            response.addFoodIds(restaurantFood.getId());// 下发美食攻略id 列表

            boolean result = RestaurantManager.checkRestaurantFoodComplete(userRestaurantInfo, restaurantFood);
            if (result) {// 成功接待,增加美食攻略的熟练度，增加人气值，有概率获得特殊奖励
                succNum++;

                totalScore += RestaurantManager.countFoodAddValue(restaurantFood, roomList, 1);// 增加人气值

                int skillValue = RestaurantManager.countFoodAddValue(restaurantFood, roomList, 0);/// 增加的熟练度

                skillValue += (int) Math.floor(skillValue * restaurantGuest.getSkillValueAdd() / 10000);// 加成后增加的熟练度

                int foodId = restaurantFood.getId();
                if (skillAddMap.containsKey(foodId)) {
                    skillValue += skillAddMap.get(foodId);
                }
                skillAddMap.put(foodId, skillValue);

                int receptionNum = 1;// 招待次数+1
                if (receptionAddMap.containsKey(foodId)) {
                    receptionNum += receptionAddMap.get(foodId);
                }
                receptionAddMap.put(foodId, receptionNum);

                //  判断概率是否获得特殊奖励
                String rewardStr = restaurantFood.sendExtraReward(pbUserData, userInfo);
                response.addRewards(rewardStr);// 下发额外奖励
            } else {
                response.addRewards("");// 下发额外奖励
            }
        }

        // 更新美食攻略的熟练度
        for (Map.Entry<Integer, Integer> entry : skillAddMap.entrySet()) {
            int foodId = entry.getKey();
            int skillValue = entry.getValue();
            UserRestaurantFood userRestaurantFood = RestaurantManager.getUserRestaurantFood(userId, foodId);
            userRestaurantFood.addSkillValue(userInfo, skillValue, LogType.RESTAURANT_GUEST_RECEPTION, foodId);
            userRestaurantFood.addReceptionNum(receptionAddMap.get(foodId));
            userRestaurantFood.update();
            ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantFood);
        }

        userRestaurantInfo.addTotalGuest(succNum);// 增加接待人数
        userRestaurantInfo.subReceptionNum(num);// 扣除接待次数
        userRestaurantInfo.addScore(pbUserData, userInfo, totalScore, LogType.RESTAURANT_GUEST_RECEPTION);
        userRestaurantInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantInfo);
        response.setSuccNum(succNum);
        if (succNum > 0) {
            RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_66, succNum);
            MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_66, succNum);
            MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_217, userRestaurantInfo.getTotalGuest());// 更新主线任务,成就,日常任务的进度
        }


        return response;
    }

    // CMD_GAME_RESTAURANT_TASK_GET_REWARD = 73307; // 领取任务奖励
    public static Object CMD_GAME_RESTAURANT_TASK_GET_REWARD(RequestParam clientParam) throws Exception {
        CSGameRestaurantTaskGetRewardRequest request = CSGameRestaurantTaskGetRewardRequest.parseFrom(clientParam.getData());
        CSGameRestaurantTaskGetRewardResponse.Builder response = CSGameRestaurantTaskGetRewardResponse.newBuilder();
        long userId = clientParam.getUserId();

        int taskId = request.getTaskId();
        RestaurantTask restaurantTask = RestaurantManager.getRestaurantTask(taskId);
        if (restaurantTask == null) {
            return ErrorWord.NOT_DATA;// 未配置
        }

        UserRestaurantInfo userRestaurantInfo = RestaurantManager.getUserRestaurantInfo(userId);
        JsonArray jsonArray = userRestaurantInfo.getTaskRewardArray();
        if (Tool.isInList(jsonArray, taskId)) {
            return ErrorWord.REPEATED_OPERATION;// 已经领取过了
        }

        UserRestaurantFood userRestaurantFood = RestaurantManager.getUserRestaurantFood(userId, restaurantTask.getFoodId());
        if (userRestaurantFood == null || userRestaurantFood.getReceptionNum() < restaurantTask.getGuestNum()) {
            return ErrorWord.ITEM_LACK;// 招待人数不足
        }

        //  执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();
        jsonArray.add(taskId);
        userRestaurantInfo.putTaskReward(jsonArray.toString());
        userRestaurantInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userRestaurantInfo);

        RewardManager.addReward(userInfo, CommonUtils.takeReawrdItemFromStr(restaurantTask.getReward()), pbUserData, LogType.RESTAURANT_TASK_REWARD, taskId);

        return response;
    }
}
